#include "FileEnumThread.h"

CFileEnumThread::CFileEnumThread(void)
{
	m_hDestWnd		=	NULL;
	m_pFileList		=	NULL;
	m_pVeFilter		=	NULL;
	m_dwThreadNum	=	10;
	m_bStop			=	false;
	m_hEvent		=	CreateEvent(NULL,FALSE,FALSE,NULL);
}

CFileEnumThread::CFileEnumThread(wstring strPath,HWND hDestWnd,CListBoxEx *pListBox,vector<wstring>* pVeFilter)
{
	m_strPath		=	strPath;
	m_hDestWnd		=	hDestWnd;
	m_pFileList		=	pListBox;
	m_pVeFilter		=	pVeFilter;
	m_dwThreadNum	=	10;
	m_bStop			=	false;
	m_hEvent		=	CreateEvent(NULL,FALSE,FALSE,NULL);
}

CFileEnumThread::~CFileEnumThread(void)
{
	m_fileEnumPool.Destroy();
	CloseHandle(m_hEvent);
}

void CFileEnumThread::SetPath(wstring strPath)
{
	m_strPath = strPath;
}

void CFileEnumThread::SetDestWindow(HWND hWnd)
{
	m_hDestWnd = hWnd;
}

void CFileEnumThread::SetListBox(CListBoxEx* pListBox)
{
	m_pFileList = pListBox;
}

void CFileEnumThread::SetThreadNum(DWORD dwThreadNum)
{
	m_dwThreadNum	= dwThreadNum;
}

void CFileEnumThread::SetFilter(vector<wstring>* pVeFilter)
{
	m_pVeFilter = pVeFilter;
}

void CFileEnumThread::Stop()
{
	m_bStop = true;
	CFileEnumJob::Stop();
}

void CFileEnumThread::DoEnum(wstring strPath)
{
	m_pFileList->DeleteAllItems();
	m_fileEnumPool.InsertJobItem(new CFileEnumJob(m_pFileList,strPath,&m_lstPath,m_hEvent,m_pVeFilter));

	while(!m_bStop)
	{
		if(!m_lstPath.size())
		{
			if(WAIT_TIMEOUT == WaitForSingleObject(m_hEvent,300))
			{
				if(!m_lstPath.size())
				{
					break;
				}
			}
		}

		if(m_lstPath.size())
		{
			CFileEnumJob::Lock();
			wstring strTmp = m_lstPath.back();
			m_lstPath.pop_back();
			CFileEnumJob::UnLock();
			m_fileEnumPool.InsertJobItem(new CFileEnumJob(m_pFileList,strTmp,&m_lstPath,m_hEvent,m_pVeFilter));
		}
	}

	m_lstPath.clear();
	InvalidateRect(m_hDestWnd,NULL,NULL);
}

void CFileEnumThread::Run()
{
	BOOL bSdIn = TRUE;

	if(!m_hDestWnd)
	{
		return;
	}

	if(!m_pFileList)
	{
		return;
	}

	if(!m_strPath.size())
	{
		return;
	}

	//list<wstring> lstDir;
	//wstring strTmp = m_strPath;
	//strTmp += L"*";
	//CUtil::EnumDir(lstDir,strTmp);

	m_fileEnumPool.Create(m_dwThreadNum);

	/*list<wstring>::iterator i,iEnd;
	iEnd = lstDir.end();
	for (i = lstDir.begin();i != iEnd; i++)
	{
		strTmp = m_strPath;
		strTmp += *i;
		m_fileEnumPool.InsertJobItem(new CFileEnumJob(m_pFileList,strTmp,&m_lstPath,m_hEvent,m_pVeFilter));
	}*/

	DoEnum(m_strPath);

	//Monitor the storage card insert or remove 

#ifndef UNDER_CE
		return;
#endif
		
		if(INVALID_FILE_ATTRIBUTES == GetFileAttributes(CUtil::GetStorageCardName().c_str()))
		{
			bSdIn = FALSE;
		}
		else
		{
			bSdIn = TRUE;
		}

		while(!m_bStop)
		{
			if(INVALID_FILE_ATTRIBUTES == GetFileAttributes(CUtil::GetStorageCardName().c_str()))
			{
				if(bSdIn) //remove
				{
					bSdIn = FALSE;

					Sleep(50);
				
					// notify the main window
					PostMessage(m_hDestWnd,WM_SDNOTIFY,SDOUT,0);

					//PlaySound(L"\\Windows\\windmin.wav", NULL, SND_FILENAME|SND_ASYNC|SND_NODEFAULT);		

					//clear the list and enum again
					DoEnum(m_strPath);
				}
				else
				{
					//do nothing
				}
			}
			else
			{
				if(!bSdIn) //insert 
				{
					bSdIn = TRUE;

					Sleep(50);

					// notify the main window
					PostMessage(m_hDestWnd,WM_SDNOTIFY,SDIN,0);

					//PlaySound(L"\\Windows\\windmax.wav", NULL, SND_FILENAME|SND_ASYNC|SND_NODEFAULT);	

					//clear the list and enum again
					DoEnum(m_strPath);
				}
				else
				{
					//do nothing
				}
			}

			Sleep(300);
		}
}
